﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


/// <summary>移動 __VIEWSTATE 到 /Form 之前.</summary>
public class MoveViewStateFilter : System.IO.MemoryStream
{
    System.IO.Stream _filter;
    bool _filtered = false;

    /// <param name="filter">A reference to the downstream HttpResponse.Filter.</param>
    public MoveViewStateFilter(System.IO.Stream filter)
    {
        _filter = filter;
    }

    /// <summary>Closes this filter stream.</summary>
    /// <remarks>
    /// The contents of this filter are written to the downstream filter after the hidden
    /// __VIEWSTATE form field is moved.
    /// </remarks>
    public override void Close()
    {
        if (_filtered)
        {
            if (this.Length > 0)
            {
                byte[] bytes;
                string content = System.Text.Encoding.UTF8.GetString(this.ToArray());
                //int viewstateStart = content.IndexOf( "<input type=\"hidden\" name=\"__CUSTOMVIEWSTATE\"" );
                int viewstateStart = content.IndexOf("<input type=\"hidden\" name=\"__CUSTOMVIEWSTATE\"");
                if (viewstateStart >= 0)
                {
                    int viewstateEnd = content.IndexOf("/>", viewstateStart) + 2;
                    string viewstate = content.Substring(viewstateStart, viewstateEnd - viewstateStart);
                    content = content.Remove(viewstateStart, viewstateEnd - viewstateStart);
                    int formEndStart = content.IndexOf("</form>");
                    if (formEndStart >= 0)
                        content = content.Insert(formEndStart, viewstate);
                    bytes = System.Text.Encoding.UTF8.GetBytes(content);
                }
                else
                {
                    bytes = this.ToArray();
                }
                _filter.Write(bytes, 0, bytes.Length);
            }
            _filter.Close();
        }
        base.Close();
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        if ((System.Web.HttpContext.Current != null)
          && ("text/html" == System.Web.HttpContext.Current.Response.ContentType))
        {
            base.Write(buffer, offset, count);
            _filtered = true;
        }
        else
        {
            _filter.Write(buffer, offset, count);
            _filtered = false;
        }
    }
}
